package com.ac.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ac.model.AuthRole;
import com.ac.model.AuthUser;
import com.ac.util.StrUtils;

import lombok.AllArgsConstructor;

@Service
@AllArgsConstructor
public class AuthRoleService {

	final MongoTemplate mongo;

	public List<AuthRole> list() {
		return mongo.findAll(AuthRole.class);
	}

	/**
	 * 获取有效角色列表
	 */
	public List<AuthRole> roleList(AuthUser authUser, Document req) {

		List<String> roleList = authUser.getRoleList();
		List<AuthRole> resList = new ArrayList<AuthRole>();
		if (roleList == null)
			return resList;
		String status = req.get("status") + "";
		Criteria ct = Criteria.where("id").exists(true);
		if (StrUtils.isNotEmpty(status)) {
			ct.and("status").is(Boolean.parseBoolean(status));
		}
		Query query = Query.query(ct);
		List<AuthRole> list = mongo.find(query, AuthRole.class);
		Set<String> resSetStr = new HashSet<String>();

		// 添加自己拥有的角色
		for (String roleId : roleList) {
			for (int i = 0; i < list.size(); i++) {
				AuthRole roleitem = list.get(i);
				if (roleitem.getId().equals(roleId)) {
					resSetStr.add(roleId);
					break;
				}
			}
		}

		// 获取用户拥有的所有角色拥有的角色id
		for (String roleId : roleList) {
			for (int i = 0; i < list.size(); i++) {
				AuthRole roleitem = list.get(i);
				if (roleitem.getId().equals(roleId)) {
					List<String> roleListT = roleitem.getRoleList();
					for (String roleIdT : roleListT)
						resSetStr.add(roleIdT);
					break;
				}
			}
		}

		// 去重后的所有角色
		for (String roleIdStr : resSetStr) {
			for (int i = 0; i < list.size(); i++) {
				AuthRole roleitem = list.get(i);
				if (roleitem.getId().equals(roleIdStr))
					resList.add(roleitem);
			}
		}

		return resList;
	}

	@Transactional(rollbackFor = Exception.class)
	public void insert(AuthRole role) {
		role.insert();
		mongo.insert(role);
	}

	@Transactional(rollbackFor = Exception.class)
	public void update(AuthRole role) {
		role.update();
		Criteria criteria = Criteria.where("id").is(role.getId());
		Query query = Query.query(criteria);
		Update update = new Update();
		update.set("title", role.getTitle());
		update.set("sort", role.getSort());
		update.set("status", role.isStatus());
		update.set("menuList", role.getMenuList());
		update.set("apiList", role.getApiList());
		update.set("roleList", role.getRoleList());
		update.set("updateTime", role.getUpdateTime());

		mongo.updateFirst(query, update, AuthRole.class);
	}

	@Transactional(rollbackFor = Exception.class)
	public void remove(AuthRole role) {

		mongo.remove(role);

		Query query = Query.query(Criteria.where("id").exists(true));
		Update pull = new Update().pull("roleList", role.getId());

		mongo.updateMulti(query, pull, AuthRole.class);
		mongo.updateMulti(query, pull, AuthUser.class);

	}

}
